Skip to main content

Attribut : pack_mode

Le pragma définit la manière dont une structure de données est compressée lors de l'allocation. L'attribut doit être inséré au-dessus de la structure de données et affecte le compactage de toute la structure.

Syntaxe:

{attribute 'pack_mode' := ' <pack mode value> '}

Emplacement d'insertion : au-dessus de la déclaration de la structure de données

Tableau 25. Valeurs possibles pour <pack mode value>

<valeur du mode pack>

Méthode d'emballage associée

La description

0

Aligné

Toutes les variables sont affectées à des adresses d'octets. Il n'y a pas de trous de mémoire.

1

Aligné sur 1 octet

2

Aligné sur 2 octets

. Il y a
  • Variables de 1 octet aux adresses d'octet

  • Variables de 2 octets aux adresses divisibles par 2. Un écart maximum de 1 octet en résulte.

  • Variables de 4 octets à des adresses divisibles par 2. Un écart maximal de 1 octet en résulte.

  • Variables de 8 octets à des adresses divisibles par 2. Un écart maximal de 1 octet en résulte.

  • Chaînes toujours aux adresses d'octet. Aucun écart n'en résulte.

4

Aligné sur 4 octets

. Il y a
  • Variables de 1 octet aux adresses d'octet

  • Variables de 2 octets aux adresses divisibles par 2. Un écart maximum de 1 octet en résulte.

  • Variables de 4 octets à des adresses divisibles par 4. Un écart maximum de 3 octets en résulte.

  • Variables de 8 octets à des adresses divisibles par 4. Un écart maximal de 3 octets en résulte.

  • Chaînes toujours aux adresses d'octet. Aucun écart n'en résulte.

8

Aligné sur 8 octets

. Il y a
  • Variables de 1 octet aux adresses d'octet

  • Variables de 2 octets aux adresses divisibles par 2. Un écart maximum de 1 octet en résulte.

  • Variables de 4 octets à des adresses divisibles par 4. Un écart maximum de 3 octets en résulte.

  • Variables de 8 octets à des adresses divisibles par 8. Un écart maximal de 7 octets en résulte.

  • Chaînes toujours aux adresses d'octet. Aucun écart n'en résulte.



Astuce

Selon la structure, il peut n'y avoir aucune différence dans le mappage de la mémoire des modes individuels. Par exemple, la distribution de la mémoire d'une structure avec le {attribute 'pack mode' := '4'} le pragma peut correspondre à celui de {attribute 'pack mode' := '8'}.

Astuce

Réseaux de structures

Si les structures sont combinées dans des tableaux, des octets sont ajoutés à la fin de la structure afin que la structure suivante soit alignée.

Important

Si la Disposition de compatibilité option est sélectionnée dans la configuration du symbole et en même temps l'attribut 'pack_mode' est utilisé dans le code, des problèmes peuvent survenir en raison d'un désalignement involontaire de la mémoire.

Exemple 1

{attribute 'pack_mode' := '1'}

TYPE myStruct:
STRUCT
  Enable: BOOL;
  Counter: INT;
  MaxSize: BOOL;
  MaxSizeReached: BOOL;
  END_STRUCT
END_TYPE

La plage de mémoire pour une variable du type de données myStruct est alloué "aligné". Si l'adresse de stockage de son composant Enable est 0x0100, par exemple, alors la composante Counter suit à l'adresse 0x0101, MaxSize à l'adresse 0x0103 et MaxSizeReached à l'adresse 0x0104. Dans le cas de 'pack_mode':=2, Counter serait à 0x0102, MaxSize à 0x0104 et MaxSizeReached à 0x0105.

Exemple 2

STRUCT
  Var1 : BOOL  := 16#01;
  Var2 : BYTE  := 16#11;
  Var3 : WORD  := 16#22;
  Var4 : BYTE  := 16#44;
  Var5 : DWORD := 16#88776655;
  Var6 : BYTE  := 16#99;
  Var7 : BYTE  := 16#AA;
  Var8 : DWORD := 16#AA;
END_TYPE

pack_mode = 8

pack_mode = 0

pack_mode = 1

pack_mode = 2

pack_mode = 4

Variable

Valeur

Variable

Valeur

Variable

Valeur

Variable

Valeur

Variable

Valeur

0

Var1

01

Var1

01

Var1

01

Var1

01

Var1

01

1

Var2

11

Var2

11

Var2

11

Var2

11

Var2

11

2

Var3

22

Var3

22

Var3

22

Var3

22

Var3

22

3

00

00

00

00

00

4

Var4

44

Var4

44

Var4

44

Var4

44

Var4

44

5

Var5

55

Var5

55

6

66

66

Var5

55

7

77

77

66

8

Var5

55

88

88

77

Var5

55

9

66

Var6

99

Var6

99

88

66

10

77

Var7

AA

Var7

AA

Var6

99

77

11

88

Var8

AA

Var8

AA

Var7

AA

88

12

Var6

99

00

00

Var8

AA

Var6

99

13

Var7

AA

00

00

00

Var7

AA

14

00

00

00

15

00

16

Var8

AA

Var8

AA

17

00

00

18

00

00

19

00

00

20

21

22

23

24

25

26

27

28

29

30

31

Exemple 3

STRUCT
    Var1 : BYTE  := 16#01;
    Var2 : LWORD := 16#11;
    Var3 : BYTE  := 16#22;
    Var4 : BYTE  := 16#44;
    Var5 : DWORD := 16#88776655;
    Var6 : BYTE  := 16#99;
    Var7 : BYTE  := 16#AA;
    Var8 : WORD  := 16#AA;
END_TYPE

pack_mode = 8

pack_mode = 0

pack_mode = 1

pack_mode = 2

pack_mode = 4

Variable

Valeur

Variable

Valeur

Variable

Valeur

Variable

Valeur

Variable

Valeur

0

Var1

01

Var1

01

Var1

01

Var1

01

Var1

01

1

Var2

11

Var2

11

2

00

00

Var2

11

3

00

00

00

4

00

00

00

Var2

11

5

00

00

00

00

6

00

00

00

00

7

00

00

00

00

8

Var2

11

00

00

00

00

9

00

Var3

22

Var3

22

00

00

10

00

Var4

44

Var4

44

Var3

22

00

11

00

Var5

55

Var5

55

Var4

44

00

12

00

66

66

Var5

55

Var3

22

13

00

77

77

66

Var4

44

14

00

88

88

77

15

00

Var6

99

Var6

99

88

16

Var3

22

Var7

AA

Var7

AA

Var6

99

Var5

55

17

Var4

44

Var8

AA

Var8

AA

Var7

AA

66

18

00

00

Var8

AA

77

19

00

88

20

Var5

55

Var6

99

21

66

Var7

AA

22

77

Var8

AA

23

88

00

24

Var6

99

25

Var7

AA

26

Var8

AA

27

00

28

29

30

31

Comportement sans 'pack-mode'

Si 'pack-mode' n'est pas utilisé, le compilateur utilise généralement le mode pack 4 ou 8, selon la description du périphérique. Dans chaque cas, un mode pack particulièrement avantageux pour le processeur est utilisé pour permettre l'accès à la mémoire. Ceci est également appelé alignement naturel ou alignement naturel des données

Effets négatifs lors de l'utilisation 'pack-mode'

Un accès mémoire non aligné peut être le résultat de l'utilisation de l'attribut 'pack_mode'. Cela signifie, par exemple, qu'un type de données d'une taille de 4 octets se trouve alors à une adresse qui n'est pas divisible par 4. Normalement, sur un système 32 bits, un type de données 32 bits peut être lu et écrit avec un accès unique à la mémoire. Sur certaines plateformes, par exemple sur les plateformes ARM, cela n'est possible que lorsque cette valeur est alignée en mémoire. Sur d'autres plateformes, il se peut que l'accès soit possible mais qu'il s'effectue beaucoup plus lentement.

{attribute 'pack_mode':=1}

TYPE DUT
STRUCT
    by1 : BYTE;
    dw1 : DWORD;
END_STRUCT
END_TYPE

Sur une plate-forme ARM, la valeur dw1 ne peut pas être lu avec un seul accès. Lorsqu'une tentative est faite pour accéder directement à cet élément, le processeur ARM lève une exception.

Hypothèse : L'accès en lecture suivant est effectué : dwTest := dut1.dw1;

Pour cet accès au DWORD dw1, quatre accès mémoire sont nécessaires car chaque octet est lu, décalé et disjoncté individuellement. Le flux est un peu le même que dans l'exemple suivant dans lequel un DWORD est généré à partir d'un tableau de quatre octets :

dwHelp := bytes[0];
dwResult := dwHelp;
dwHelp := bytes[1];
dwHelp := SHL(dwHelp, 8);
dwResult := dwResult OR dwHelp;
dwHelp := bytes[2];
dwHelp := SHL(dwHelp, 16);
dwResult := dwResult OR dwHelp;
dwHelp := bytes[3];
dwHelp := SHL(dwHelp, 24);
dwResult := dwResult OR dwHelp;

Évidemment, ce type d'accès est beaucoup plus lent que l'accès à un DWORD, qui est correctement aligné dans la mémoire.

pdw := ADR(dut1.dw1);
dwTest := pdw^;

Cependant, le compilateur ne générera pas l'accès de l'exemple lorsque ce type de membre est accédé au moyen d'un pointeur. Cela signifie que le code suivant génère une exception sur une plate-forme ARM.

pdw := ADR(dut1.dw1);
dwTest := pdw^;

Pour des raisons de performances, il faut donc éviter de travailler avec des structures qui ne sont pas naturellement alignées.

Une structure emballée ne doit pas contenir une structure non emballée.